# 开发的主要目录，代码基本都在这个目录中

# 3.1 导包Redis


import redis
# 11.2导包
import logging

from flask import Flask
# 2.1 导包 数据库SQLAlchemy扩展
from flask_sqlalchemy import SQLAlchemy
# 4.1 导包flask_wtf.csrf  CSRFProtect
# 导入生成csrf_token值的函数
from flask_wtf.csrf import CSRFProtect, generate_csrf
# 5.4 导包Session
from flask_session import Session
# 8.1抽取导包
# from config import DevelopmentConfig
# 11.2导包
from logging.handlers import RotatingFileHandler


# 2.2 创建数据库


db = SQLAlchemy()

# 14.1定义空redis存储对象 增加类型注释来查看
redis_store = None  # type: redis.StrictRedis

# 11.创建日志
# 11.6 封装函数
def setup_log(Config_name):
    # 设置日志的记录等级
    # 11.8参数
    logging.basicConfig(level=Config_name.LOG_LEVEL)  # 调试debug级A
    # 创建日志记录器，指明日志保存的路径、每个日志文件的最大大小、保存的日志文件个数上限
    file_log_handler = RotatingFileHandler("logs/log", maxBytes=1024 * 1024 * 100, backupCount=10)
    # 创建日志记录的格式 日志等级 输入日志信息的文件名 行数 日志信息
    formatter = logging.Formatter('%(levelname)s %(filename)s:%(lineno)d %(message)s')
    # 为刚创建的日志记录器设置日志记录格式
    file_log_handler.setFormatter(formatter)
    # 为全局的日志工具对象（flask app使用的）添加日志记录器
    logging.getLogger().addHandler(file_log_handler)


# 10.2提供一个函数，工厂方法，方便的根据不同的参数，实现不同的配置加载
def create_app(Config_name):
    # 11.7配置项目日志
    setup_log(Config_name)

    # app实例化
    app = Flask(__name__)

    # 查找app的配置
    # app.permanent_session_lifetime

    # 5.2找到秘钥的源码
    # app.secret_key

    # 1.2 app绑定配置
    # 2.4 传参
    app.config.from_object(Config_name)

    # 几乎所有的扩展都支持这种创建方式
    db.init_app(app)

    # 3.2 创建redis对象 添加decode_responses
    global redis_store
    redis_store = redis.StrictRedis(host=Config_name.REDIS_HOST, port=Config_name.REDIS_PORT, decode_responses=True)

    # 4.2 开启CSRF保护 》 会启用csrf_token对比机制
    # 1.wtf中有函数可以直接生成
    # 2.在请求钩子中进行设置
    # 3.ajax可以增加一个字段：headers:("X-CSRFToken")
    # 4.到时候会自动从cookie中获取csrftoken,从ajax的参数中获取csrftoken,然后进行对比

    CSRFProtect(app)

    # 将scrf_token的值传给前端浏览器，思路：可以在请求钩子中完成此逻辑
    # 2.在每次请求之后，生成csrf_token，设置到cookie中
    @app.after_request
    def after_request(response):
        # token生成后，会缓存起来，多次生成仍是同一个
        # 调用函数生成 csrf_token
        csrf_token = generate_csrf()
        # WTF扩展会自动将corf_token存入session，然后通过flas—session扩展同步到服务器的redis中
        # 通过 cookie 将值传给前端 第一个是key值，第二个是要传入的值
        response.set_cookie("csrf_token", csrf_token)
        return response

    # 首页点击排行自定义过滤器导包
    from info.utils.common import do_index_class
    # 增加自定义过滤器
    app.add_template_filter(do_index_class, 'index_class')

    # 5.5 设置Flask-Session扩展
    # 将存在浏览器的cookie中的session数据，同步到服务器的指定地址中(redis)
    Session(app)

    # 蓝图在用到的时候再导包，可以当作固定规则
    # 13.2蓝图导包
    from info.modules.index import index_blue
    # 13.注册蓝图
    app.register_blueprint(index_blue)

    # 13.2 passport蓝图导包
    from info.modules.passport import passport_blue
    # 13.注册蓝图
    app.register_blueprint(passport_blue)

    # 13.2 news蓝图导包
    from info.modules.news import news_blue
    # 13.注册蓝图
    app.register_blueprint(news_blue)

    # 13.2 个人中心蓝图导包
    from info.modules.profile import profile_blue
    # 13.注册蓝图
    app.register_blueprint(profile_blue)

    return app

